/* -*- mode: c; tab-width: 4; c-basic-offset: 3; c-file-style: "linux" -*- */
//
// Copyright (c) 2009, Wei Mingzhi <whistler_wmz@users.sf.net>.
// All rights reserved.
//
// This file is part of SDLPAL.
//
// SDLPAL is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

#ifndef GLOBAL_H
#define GLOBAL_H

#include "_common.h"
#include "map.h"
#include "ui.h"

#ifdef __cplusplus
extern "C" {
#endif

//
// SOME NOTES ON "AUTO SCRIPT" AND "TRIGGER SCRIPT":
//
// Auto scripts are executed automatically in each frame.
//
// Trigger scripts are only executed when the event is triggered (player touched
// an event object, player triggered an event script by pressing Spacebar).
//

// maximum number of players in party
#define MAX_PLAYERS_IN_PARTY 3

// total number of possible player roles
#define MAX_PLAYER_ROLES 6

// totally number of playable player roles
#define MAX_PLAYABLE_PLAYER_ROLES 5

// maximum entries of inventory
#define MAX_INVENTORY 256

// maximum items in a store
#define MAX_STORE_ITEM 9

// total number of magic attributes
#define NUM_MAGIC_ELEMENTAL 5

// maximum number of enemies in a team
#define MAX_ENEMIES_IN_TEAM 5

// maximum number of equipments for a player
#define MAX_PLAYER_EQUIPMENTS 6

// maximum number of magics for a player
#define MAX_PLAYER_MAGICS 32

// maximum number of scenes
#define MAX_SCENES 300

// maximum number of objects
#define MAX_OBJECTS 600

// maximum number of event objects (should be somewhat more than the original,
// as there are some modified versions which has more)
#define MAX_EVENT_OBJECTS 5500

// maximum number of effective poisons to players
#define MAX_POISONS 16

// maximum number of level
#define MAX_LEVELS 99

// status of characters
typedef enum tagSTATUS {
   kStatusConfused = 0, // attack friends randomly
#ifdef PAL_CLASSIC
   kStatusParalyzed, // paralyzed
#else
   kStatusSlow, // slower
#endif
   kStatusSleep,      // not allowed to move
   kStatusSilence,    // cannot use magic
   kStatusPuppet,     // for dead players only, continue attacking
   kStatusBravery,    // more power for physical attacks
   kStatusProtect,    // more defense value
   kStatusHaste,      // faster
   kStatusDualAttack, // dual attack
   kStatusAll
} STATUS;

#ifndef PAL_CLASSIC
#define kStatusParalyzed kStatusSleep
#endif

// body parts of equipments
typedef enum tagBODYPART {
   kBodyPartHead = 0,
   kBodyPartBody,
   kBodyPartShoulder,
   kBodyPartHand,
   kBodyPartFeet,
   kBodyPartWear,
   kBodyPartExtra,
} BODYPART;

// state of event object, used by the sState field of the EVENTOBJECT struct
typedef enum tagOBJECTSTATE {
   kObjStateHidden = 0,
   kObjStateNormal = 1,
   kObjStateBlocker = 2
} OBJECTSTATE,
    *LPOBJECTSTATE;

typedef enum tagTRIGGERMODE {
   kTriggerNone = 0,
   kTriggerSearchNear = 1,
   kTriggerSearchNormal = 2,
   kTriggerSearchFar = 3,
   kTriggerTouchNear = 4,
   kTriggerTouchNormal = 5,
   kTriggerTouchFar = 6,
   kTriggerTouchFarther = 7,
   kTriggerTouchFarthest = 8
} TRIGGERMODE;

typedef struct tagEVENTOBJECT
{
   SHORT sVanishTime;              // vanish time (?)
   WORD x;                         // X coordinate on the map
   WORD y;                         // Y coordinate on the map
   SHORT sLayer;                   // layer value
   WORD wTriggerScript;            // Trigger script entry
   WORD wAutoScript;               // Auto script entry
   SHORT sState;                   // state of this object
   WORD wTriggerMode;              // trigger mode
   WORD wSpriteNum;                // number of the sprite
   USHORT nSpriteFrames;           // total number of frames of the sprite
   WORD wDirection;                // direction
   WORD wCurrentFrameNum;          // current frame number
   USHORT nScriptIdleFrame;        // count of idle frames, used by trigger script
   WORD wSpritePtrOffset;          // FIXME: ???
   USHORT nSpriteFramesAuto;       // total number of frames of the sprite, used by auto script
   WORD wScriptIdleFrameCountAuto; // count of idle frames, used by auto script
} EVENTOBJECT, *LPEVENTOBJECT;

typedef struct tagSCENE
{
   WORD wMapNum;           // number of the map
   WORD wScriptOnEnter;    // when entering this scene, execute script from here
   WORD wScriptOnTeleport; // when teleporting out of this scene, execute script from here
   WORD wEventObjectIndex; // event objects in this scene begins from number wEventObjectIndex + 1
} SCENE, *LPSCENE;

// object including system strings, players, items, magics, enemies and poison scripts.

// system strings and players
typedef struct tagOBJECT_PLAYER
{
   WORD wReserved[2];         // always zero
   WORD wScriptOnFriendDeath; // when friends in party dies, execute script from here
   WORD wScriptOnDying;       // when dying, execute script from here
} OBJECT_PLAYER;

typedef enum tagITEMFLAG {
   kItemFlagUsable = (1 << 0),
   kItemFlagEquipable = (1 << 1),
   kItemFlagThrowable = (1 << 2),
   kItemFlagConsuming = (1 << 3),
   kItemFlagApplyToAll = (1 << 4),
   kItemFlagSellable = (1 << 5),
   kItemFlagEquipableByPlayerRole_First = (1 << 6)
} ITEMFLAG;

// items
typedef struct tagOBJECT_ITEM
{
   WORD wBitmap;        // bitmap number in BALL.MKF
   WORD wPrice;         // price
   WORD wScriptOnUse;   // script executed when using this item
   WORD wScriptOnEquip; // script executed when equipping this item
   WORD wScriptOnThrow; // script executed when throwing this item to enemy
#ifdef PAL_WIN95
   WORD wScriptDesc; // description script
#endif
   WORD wFlags; // flags
} OBJECT_ITEM;

typedef enum tagMAGICFLAG {
   kMagicFlagUsableOutsideBattle = (1 << 0),
   kMagicFlagUsableInBattle = (1 << 1),
   kMagicFlagUsableToEnemy = (1 << 3),
   kMagicFlagApplyToAll = (1 << 4),
} MAGICFLAG;

// magics
typedef struct tagOBJECT_MAGIC
{
   WORD wMagicNumber;     // magic number, according to DATA.MKF #3
   WORD wReserved1;       // always zero
   WORD wScriptOnSuccess; // when magic succeed, execute script from here
   WORD wScriptOnUse;     // when use this magic, execute script from here
#ifdef PAL_WIN95
   WORD wScriptDesc; // description script
#endif
   WORD wReserved2; // always zero
   WORD wFlags;     // flags
} OBJECT_MAGIC;

// enemies
typedef struct tagOBJECT_ENEMY
{
   WORD wEnemyID;             // ID of the enemy, according to DATA.MKF #1.
                              // Also indicates the bitmap number in ABC.MKF.
   WORD wResistanceToSorcery; // resistance to sorcery and poison (0 min, 10 max)
   WORD wScriptOnTurnStart;   // script executed when turn starts
   WORD wScriptOnBattleEnd;   // script executed when battle ends
   WORD wScriptOnReady;       // script executed when the enemy is ready
} OBJECT_ENEMY;

// poisons (scripts executed in each round)
typedef struct tagOBJECT_POISON
{
   WORD wPoisonLevel;  // level of the poison
   WORD wColor;        // color of avatars
   WORD wPlayerScript; // script executed when player has this poison (per round)
   WORD wReserved;     // always zero
   WORD wEnemyScript;  // script executed when enemy has this poison (per round)
} OBJECT_POISON;

typedef union tagOBJECT {
#ifdef PAL_WIN95
   WORD rgwData[7];
#else
   WORD rgwData[6];
#endif
   OBJECT_PLAYER player;
   OBJECT_ITEM item;
   OBJECT_MAGIC magic;
   OBJECT_ENEMY enemy;
   OBJECT_POISON poison;
} OBJECT, *LPOBJECT;

typedef struct tagSCRIPTENTRY
{
   WORD wOperation;    // operation code
   WORD rgwOperand[3]; // operands
} SCRIPTENTRY, *LPSCRIPTENTRY;

typedef struct tagINVENTORY
{
   WORD wItem;          // item object code
   USHORT nAmount;      // amount of this item
   USHORT nAmountInUse; // in-use amount of this item
} INVENTORY, *LPINVENTORY;

typedef struct tagSTORE
{
   WORD rgwItems[MAX_STORE_ITEM];
} STORE, *LPSTORE;

typedef struct tagENEMY
{
   WORD wIdleFrames;    // total number of frames when idle
   WORD wMagicFrames;   // total number of frames when using magics
   WORD wAttackFrames;  // total number of frames when doing normal attack
   WORD wIdleAnimSpeed; // speed of the animation when idle
   WORD wActWaitFrames; // FIXME: ???
   WORD wYPosOffset;
   WORD wAttackSound;                         // sound played when this enemy uses normal attack
   WORD wActionSound;                         // FIXME: ???
   WORD wMagicSound;                          // sound played when this enemy uses magic
   WORD wDeathSound;                          // sound played when this enemy dies
   WORD wCallSound;                           // sound played when entering the battle
   WORD wHealth;                              // total HP of the enemy
   WORD wExp;                                 // How many EXPs we'll get for beating this enemy
   WORD wCash;                                // how many cashes we'll get for beating this enemy
   WORD wLevel;                               // this enemy's level
   WORD wMagic;                               // this enemy's magic number
   WORD wMagicRate;                           // chance for this enemy to use magic
   WORD wAttackEquivItem;                     // equivalence item of this enemy's normal attack
   WORD wAttackEquivItemRate;                 // chance for equivalence item
   WORD wStealItem;                           // which item we'll get when stealing from this enemy
   USHORT nStealItem;                         // total amount of the items which can be stolen
   WORD wAttackStrength;                      // normal attack strength
   WORD wMagicStrength;                       // magical attack strength
   WORD wDefense;                             // resistance to all kinds of attacking
   WORD wDexterity;                           // dexterity
   WORD wFleeRate;                            // chance for successful fleeing
   WORD wPoisonResistance;                    // resistance to poison
   WORD wElemResistance[NUM_MAGIC_ELEMENTAL]; // resistance to elemental magics
   WORD wPhysicalResistance;                  // resistance to physical attack
   WORD wDualMove;                            // whether this enemy can do dual move or not
   WORD wCollectValue;                        // value for collecting this enemy for items
} ENEMY, *LPENEMY;

typedef struct tagENEMYTEAM
{
   WORD rgwEnemy[MAX_ENEMIES_IN_TEAM];
} ENEMYTEAM, *LPENEMYTEAM;

typedef WORD PLAYERS[MAX_PLAYER_ROLES];

typedef struct tagPLAYERROLES
{
   PLAYERS rgwAvatar;                                                  // avatar (shown in status view)
   PLAYERS rgwSpriteNumInBattle;                                       // sprite displayed in battle (in F.MKF)
   PLAYERS rgwSpriteNum;                                               // sprite displayed in normal scene (in MGO.MKF)
   PLAYERS rgwName;                                                    // name of player class (in WORD.DAT)
   PLAYERS rgwAttackAll;                                               // whether player can attack everyone in a bulk or not
   PLAYERS rgwUnknown1;                                                // FIXME: ???
   PLAYERS rgwLevel;                                                   // level
   PLAYERS rgwMaxHP;                                                   // maximum HP
   PLAYERS rgwMaxMP;                                                   // maximum MP
   PLAYERS rgwHP;                                                      // current HP
   PLAYERS rgwMP;                                                      // current MP
   WORD rgwEquipment[MAX_PLAYER_EQUIPMENTS][MAX_PLAYER_ROLES];         // equipments
   PLAYERS rgwAttackStrength;                                          // normal attack strength
   PLAYERS rgwMagicStrength;                                           // magical attack strength
   PLAYERS rgwDefense;                                                 // resistance to all kinds of attacking
   PLAYERS rgwDexterity;                                               // dexterity
   PLAYERS rgwFleeRate;                                                // chance of successful fleeing
   PLAYERS rgwPoisonResistance;                                        // resistance to poison
   WORD rgwElementalResistance[NUM_MAGIC_ELEMENTAL][MAX_PLAYER_ROLES]; // resistance to elemental magics
   PLAYERS rgwUnknown2;                                                // FIXME: ???
   PLAYERS rgwUnknown3;                                                // FIXME: ???
   PLAYERS rgwUnknown4;                                                // FIXME: ???
   PLAYERS rgwCoveredBy;                                               // who will cover me when I am low of HP or not sane
   WORD rgwMagic[MAX_PLAYER_MAGICS][MAX_PLAYER_ROLES];                 // magics
   PLAYERS rgwWalkFrames;                                              // walk frame (???)
   PLAYERS rgwCooperativeMagic;                                        // cooperative magic
   PLAYERS rgwUnknown5;                                                // FIXME: ???
   PLAYERS rgwUnknown6;                                                // FIXME: ???
   PLAYERS rgwDeathSound;                                              // sound played when player dies
   PLAYERS rgwAttackSound;                                             // sound played when player attacks
   PLAYERS rgwWeaponSound;                                             // weapon sound (???)
   PLAYERS rgwCriticalSound;                                           // sound played when player make critical hits
   PLAYERS rgwMagicSound;                                              // sound played when player is casting a magic
   PLAYERS rgwCoverSound;                                              // sound played when player cover others
   PLAYERS rgwDyingSound;                                              // sound played when player is dying
} PLAYERROLES, *LPPLAYERROLES;

typedef enum tagMAGIC_TYPE {
   kMagicTypeNormal = 0,
   kMagicTypeAttackAll = 1,     // draw the effect on each of the enemies
   kMagicTypeAttackWhole = 2,   // draw the effect on the whole enemy team
   kMagicTypeAttackField = 3,   // draw the effect on the battle field
   kMagicTypeApplyToPlayer = 4, // the magic is used on one player
   kMagicTypeApplyToParty = 5,  // the magic is used on the whole party
   kMagicTypeTrance = 8,        // trance the player
   kMagicTypeSummon = 9,        // summon
} MAGIC_TYPE;

typedef struct tagMAGIC
{
   WORD wEffect; // effect sprite
   WORD wType;   // type of this magic
   WORD wXOffset;
   WORD wYOffset;
   WORD wSummonEffect; // summon effect sprite (in F.MKF)
   WORD wSpeed;        // speed of the effect
   WORD wKeepEffect;   // FIXME: ???
   WORD wSoundDelay;   // delay of the SFX
   WORD wEffectTimes;  // total times of effect
   WORD wShake;        // shake screen
   WORD wWave;         // wave screen
   WORD wUnknown;      // FIXME: ???
   WORD wCostMP;       // MP cost
   WORD wBaseDamage;   // base damage
   WORD wElemental;    // elemental (0 = No Elemental, last = poison)
   WORD wSound;        // sound played when using this magic
} MAGIC, *LPMAGIC;

typedef struct tagBATTLEFIELD
{
   WORD wScreenWave;                          // level of screen waving
   SHORT rgsMagicEffect[NUM_MAGIC_ELEMENTAL]; // effect of attributed magics
} BATTLEFIELD, *LPBATTLEFIELD;

// magics learned when level up
typedef struct tagLEVELUPMAGIC
{
   WORD wLevel; // level reached
   WORD wMagic; // magic learned
} LEVELUPMAGIC, *LPLEVELUPMAGIC;

typedef struct tagLEVELUPMAGIC_ALL
{
   LEVELUPMAGIC m[MAX_PLAYABLE_PLAYER_ROLES];
} LEVELUPMAGIC_ALL, *LPLEVELUPMAGIC_ALL;

typedef struct tagENEMYPOS
{
   struct
   {
      WORD x;
      WORD y;
   } pos[MAX_ENEMIES_IN_TEAM][MAX_ENEMIES_IN_TEAM];
} ENEMYPOS, *LPENEMYPOS;

// Exp. points needed for the next level
typedef WORD LEVELUPEXP, *LPLEVELUPEXP;

// game data which is available in data files.
typedef struct tagGAMEDATA
{
   LPEVENTOBJECT lprgEventObject;
   int nEventObject;

   SCENE rgScene[MAX_SCENES];
   OBJECT rgObject[MAX_OBJECTS];

   LPSCRIPTENTRY lprgScriptEntry;
   int nScriptEntry;

   LPSTORE lprgStore;
   int nStore;

   LPENEMY lprgEnemy;
   int nEnemy;

   LPENEMYTEAM lprgEnemyTeam;
   int nEnemyTeam;

   PLAYERROLES PlayerRoles;

   LPMAGIC lprgMagic;
   int nMagic;

   LPBATTLEFIELD lprgBattleField;
   int nBattleField;

   LPLEVELUPMAGIC_ALL lprgLevelUpMagic;
   int nLevelUpMagic;

   ENEMYPOS EnemyPos;
   LEVELUPEXP rgLevelUpExp[MAX_LEVELS + 1];

   WORD rgwBattleEffectIndex[10][2];
} GAMEDATA, *LPGAMEDATA;

typedef struct tagFILES
{
   FILE *fpFBP;  // battlefield background images
   FILE *fpMGO;  // sprites in scenes
   FILE *fpBALL; // item bitmaps
   FILE *fpDATA; // misc data
   FILE *fpF;    // player sprites during battle
   FILE *fpFIRE; // fire effect sprites
   FILE *fpRGM;  // character face bitmaps
   FILE *fpSSS;  // script data
} FILES, *LPFILES;

// player party
typedef struct tagPARTY
{
   WORD wPlayerRole;  // player role
   SHORT x, y;        // position
   WORD wFrame;       // current frame number
   WORD wImageOffset; // FIXME: ???
} PARTY, *LPPARTY;

// player trail, used for other party members to follow the main party member
typedef struct tagTRAIL
{
   WORD x, y;       // position
   WORD wDirection; // direction
} TRAIL, *LPTRAIL;

typedef struct tagEXPERIENCE
{
   WORD wExp; // current experience points
   WORD wReserved;
   WORD wLevel; // current level
   WORD wCount;
} EXPERIENCE, *LPEXPERIENCE;

typedef struct tagALLEXPERIENCE
{
   EXPERIENCE rgPrimaryExp[MAX_PLAYER_ROLES];
   EXPERIENCE rgHealthExp[MAX_PLAYER_ROLES];
   EXPERIENCE rgMagicExp[MAX_PLAYER_ROLES];
   EXPERIENCE rgAttackExp[MAX_PLAYER_ROLES];
   EXPERIENCE rgMagicPowerExp[MAX_PLAYER_ROLES];
   EXPERIENCE rgDefenseExp[MAX_PLAYER_ROLES];
   EXPERIENCE rgDexterityExp[MAX_PLAYER_ROLES];
   EXPERIENCE rgFleeExp[MAX_PLAYER_ROLES];
} ALLEXPERIENCE, *LPALLEXPERIENCE;

typedef struct tagPOISONSTATUS
{
   WORD wPoisonID;     // kind of the poison
   WORD wPoisonScript; // script entry
} POISONSTATUS, *LPPOISONSTATUS;

typedef struct tagGLOBALVARS
{
   FILES f;
   GAMEDATA g;

   BYTE bCurrentSaveSlot;  // current save slot (1-5)
   int iCurMainMenuItem;   // current main menu item number
   int iCurSystemMenuItem; // current system menu item number
   int iCurInvMenuItem;    // current inventory menu item number
   int iCurPlayingRNG;     // current playing RNG animation
   BOOL fGameStart;        // TRUE if the has just started
   BOOL fEnteringScene;    // TRUE if entering a new scene
   BOOL fNeedToFadeIn;     // TRUE if need to fade in when drawing scene
   BOOL fInBattle;         // TRUE if in battle
   BOOL fAutoBattle;       // TRUE if auto-battle
#ifndef PAL_CLASSIC
   BYTE bBattleSpeed; // Battle Speed (1 = Fastest, 5 = Slowest)
#endif
   WORD wLastUnequippedItem; // last unequipped item

   PLAYERROLES rgEquipmentEffect[MAX_PLAYER_EQUIPMENTS + 1]; // equipment effects
   WORD rgPlayerStatus[MAX_PLAYER_ROLES][kStatusAll];        // player status

   PAL_POS viewport; // viewport coordination
   PAL_POS partyoffset;
   WORD wLayer;
   WORD wMaxPartyMemberIndex;                // max index of members in party (0 to MAX_PLAYERS_IN_PARTY - 1)
   PARTY rgParty[MAX_PLAYABLE_PLAYER_ROLES]; // player party
   TRAIL rgTrail[MAX_PLAYABLE_PLAYER_ROLES]; // player trail
   WORD wPartyDirection;                     // direction of the party
   WORD wNumScene;                           // current scene number
   WORD wNumPalette;                         // current palette number
   BOOL fNightPalette;                       // TRUE if use the darker night palette
   WORD wNumMusic;                           // current music number
   WORD wNumBattleMusic;                     // current music number in battle
   WORD wNumBattleField;                     // current battle field number
   WORD wCollectValue;                       // value of "collected" items
   WORD wScreenWave;                         // level of screen waving
   SHORT sWaveProgression;
   WORD wChaseRange;
   WORD wChasespeedChangeCycles;
   USHORT nFollower;

   DWORD dwCash; // amount of cash

   ALLEXPERIENCE Exp;                                                   // experience status
   POISONSTATUS rgPoisonStatus[MAX_POISONS][MAX_PLAYABLE_PLAYER_ROLES]; // poison status
   INVENTORY rgInventory[MAX_INVENTORY];                                // inventory status
#ifndef PAL_WIN95
   LPOBJECTDESC lpObjectDesc;
#endif
   DWORD dwFrameNum;
} GLOBALVARS, *LPGLOBALVARS;

typedef struct tagSAVEDGAME
{
   WORD wSavedTimes;            // saved times
   WORD wViewportX, wViewportY; // viewport location
   WORD nPartyMember;           // number of members in party
   WORD wNumScene;              // scene number
   WORD wPaletteOffset;
   WORD wPartyDirection; // party direction
   WORD wNumMusic;       // music number
   WORD wNumBattleMusic; // battle music number
   WORD wNumBattleField; // battle field number
   WORD wScreenWave;     // level of screen waving
   WORD wBattleSpeed;    // battle speed
   WORD wCollectValue;   // value of "collected" items
   WORD wLayer;
   WORD wChaseRange;
   WORD wChasespeedChangeCycles;
   WORD nFollower;
   WORD rgwReserved2[3];                     // unused
   DWORD dwCash;                             // amount of cash
   PARTY rgParty[MAX_PLAYABLE_PLAYER_ROLES]; // player party
   TRAIL rgTrail[MAX_PLAYABLE_PLAYER_ROLES]; // player trail
   ALLEXPERIENCE Exp;                        // experience data
   PLAYERROLES PlayerRoles;
   POISONSTATUS rgPoisonStatus[MAX_POISONS][MAX_PLAYABLE_PLAYER_ROLES]; // poison status
   INVENTORY rgInventory[MAX_INVENTORY];                                // inventory status
   SCENE rgScene[MAX_SCENES];
   OBJECT rgObject[MAX_OBJECTS];
   EVENTOBJECT rgEventObject[MAX_EVENT_OBJECTS];
} SAVEDGAME, *LPSAVEDGAME;

extern LPGLOBALVARS gpGlobals;

INT
    PAL_InitGlobals(
        VOID);

VOID
    PAL_FreeGlobals(
        VOID);

VOID PAL_SaveGame(
    LPCSTR szFileName,
    WORD wSavedTimes);

VOID PAL_InitGameData(
    INT iSaveSlot);

BOOL PAL_AddItemToInventory(
    WORD wObjectID,
    INT iNum);

BOOL PAL_IncreaseHPMP(
    WORD wPlayerRole,
    SHORT sHP,
    SHORT sMP);

INT PAL_GetItemAmount(
    WORD wItem);

VOID
    PAL_UpdateEquipments(
        VOID);

VOID
    PAL_CompressInventory(
        VOID);

VOID PAL_RemoveEquipmentEffect(
    WORD wPlayerRole,
    WORD wEquipPart);

VOID PAL_AddPoisonForPlayer(
    WORD wPlayerRole,
    WORD wPoisonID);

VOID PAL_CurePoisonByKind(
    WORD wPlayerRole,
    WORD wPoisonID);

VOID PAL_CurePoisonByLevel(
    WORD wPlayerRole,
    WORD wMaxLevel);

BOOL PAL_IsPlayerPoisonedByLevel(
    WORD wPlayerRole,
    WORD wMinLevel);

BOOL PAL_IsPlayerPoisonedByKind(
    WORD wPlayerRole,
    WORD wPoisonID);

WORD PAL_GetPlayerAttackStrength(
    WORD wPlayerRole);

WORD PAL_GetPlayerMagicStrength(
    WORD wPlayerRole);

WORD PAL_GetPlayerDefense(
    WORD wPlayerRole);

WORD PAL_GetPlayerDexterity(
    WORD wPlayerRole);

WORD PAL_GetPlayerFleeRate(
    WORD wPlayerRole);

WORD PAL_GetPlayerPoisonResistance(
    WORD wPlayerRole);

WORD PAL_GetPlayerElementalResistance(
    WORD wPlayerRole,
    INT iAttrib);

WORD PAL_GetPlayerBattleSprite(
    WORD wPlayerRole);

WORD PAL_GetPlayerCooperativeMagic(
    WORD wPlayerRole);

BOOL PAL_PlayerCanAttackAll(
    WORD wPlayerRole);

BOOL PAL_AddMagic(
    WORD wPlayerRole,
    WORD wMagic);

VOID PAL_RemoveMagic(
    WORD wPlayerRole,
    WORD wMagic);

VOID PAL_SetPlayerStatus(
    WORD wPlayerRole,
    WORD wStatusID,
    WORD wNumRound);

VOID PAL_RemovePlayerStatus(
    WORD wPlayerRole,
    WORD wStatusID);

VOID
    PAL_ClearAllPlayerStatus(
        VOID);

VOID PAL_PlayerLevelUp(
    WORD wPlayerRole,
    WORD wNumLevel);

#ifdef __cplusplus
}
#endif

#endif
